/*
 * spi.h
 *
 * spi driver.
 * only support Master mode
 * 
 * Copyright (C) 2022 Microwell, Inc.
 * Subject to the GNU Public License, version 2.
 *
 * Author: guoming<guoming@microwell.net>
 */
#ifndef __SPI_H__
#define __SPI_H__

#include "core.h"

typedef enum {
    first_spi,
    sencond_spi,
} spi_nss_select;

/**
 * @brief 如果使能模拟spi，将会屏蔽硬件spi
 * 为了保证io操作的时效性，尽量不要使用efr操作的GPIO(P15~P22)
 * 
 */
#define CONFIG_SORFWARE_SPI                        (RESET)

/**
 * @brief SPI 模式选择
 * 1：全双工模式 4wires
 * 0：半双工模式（MISO复用到MOSI）3wires
 */
#define CONFIG_SPI_MODE                            (SET)

/*
 * SPI I/O operation definition, for example: P10
 * I/O operation: _P10_EN(SET), _P10_EN(SET)
 * I/O read: _P10
 * I/O mode: _P10_IO_INPUT(), _P10_IO_OUTPUT()
 */

#define CSN_HIGH()                                 _P10_EN(SET)
#define CSN_LOW()                                  _P10_EN(RESET)
#define CSN_OUTPUT_MODE()                          _P10_IO_OUTPUT()

#define SCK_HIGH()                                 _P11_EN(SET)
#define SCK_LOW()                                  _P11_EN(RESET)
#define SCK_OUTPUT_MODE()                          _P11_IO_OUTPUT()


#if (CONFIG_SPI_MODE == 0)

#define SIO_INPUT_MODE()                           _P10_IO_INPUT()
#define SIO_STATUS()                               _P12
#define SIO_OUTPUT_MODE()                          _P12_IO_OUTPUT()
#define SIO_HIGH()                                 _P12_EN(SET)
#define SIO_LOW()                                  _P12_EN(RESET)

#elif (CONFIG_SPI_MODE == 1)

#define MOSI_OUTPUT_MODE()                         _P12_IO_OUTPUT()
#define MOSI_HIGH()                                _P12_EN(SET)
#define MOSI_LOW()                                 _P12_EN(RESET)


#define MISO_INPUT_MODE()                          _P13_IO_INPUT()
#define MISO_STATUS()                              _P13

#endif

#if (CONFIG_IC_TYPE == CHIP_SS888X)
#define SPI_RX_FIFO_NO_EMPTY()                     (!!READ_BIT(SPIINTSTAT, SPI_RX_FIFO_FLAG))
#define SPI_TX_FIFO_SEND_OK()                      (!!READ_BIT(SPIINTSTAT, SPI_TX_FIFO_FLAG))

#if (SPI_CHANNEL_MODE)
void spi_cs_low(void);
void spi_cs_high(void);
void spi_ww(uint8_t r_reg);
void spi_wr(uint8_t r_reg);
uint8_t spi_read_byte(void);

void spi_init(void);
void spi_exit(void);
void spi_write_reg(uint8_t reg,  uint8_t val);
void spi_write_buf(uint8_t reg, uint8_t *buf, uint8_t len);
uint8_t spi_read_reg(uint8_t reg);
void spi_read_buf(uint8_t reg, uint8_t *buf, uint8_t len);
void spi_select_ss(spi_nss_select ss);
#else
#define spi_cs_low()
#define spi_cs_high()
#define spi_ww(r_reg)
#define spi_wr(r_reg)
#define spi_read_byte()    (0)

#define spi_init()
#define spi_exit()
#define spi_write_reg(reg, val)
#define spi_write_buf(reg, buf, len)
#define spi_read_reg(reg)           (0)
#define spi_read_buf(reg, buf, len)
#define spi_select_ss(ss)
#endif
#endif


#endif